﻿/* EntitiesToDTOs. Copyright (c) 2011. Fabian Fernandez.
 * http://entitiestodtos.codeplex.com
 * Licensed by Common Development and Distribution License (CDDL).
 * http://entitiestodtos.codeplex.com/license
 * Fabian Fernandez. 
 * http://www.linkedin.com/in/fabianfernandezb/en
 * */
using EnvDTE;
using EnvDTE80;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Threading;
using EntitiesToDTOs.Enums;
using EntitiesToDTOs.Events;
using EntitiesToDTOs.Generators;
using EntitiesToDTOs.Generators.Parameters;
using EntitiesToDTOs.Helpers;
using EntitiesToDTOs.Properties;
using Microsoft.VisualStudio.Shell;

namespace EntitiesToDTOs.UI
{
    /// <summary>
    /// Main Window of the AddIn
    /// </summary>
    public partial class MainWindow : Form
    {
        /// <summary>
        /// Represents the IDE (Visual Studio)
        /// </summary>
        private DTE2 _applicationObject;

        /// <summary>
        /// Reference to the ProgressWindow used to show the process progress
        /// </summary>
        private GenerationProgressWindow ProgressWindow { get; set; }


        /// <summary>
        /// Creates a new instance of MainWindow
        /// </summary>
        /// <param name="applicationObject"></param>
        public MainWindow(DTE2 applicationObject)
        {
            InitializeComponent();

            try
            {
                // Set Window Caption
                this.Text = string.Format(Resources.MainWindow_Caption, AssemblyHelper.Version);

                // Set the object that represents the IDE (Visual Studio)
                _applicationObject = applicationObject;

                // Check if there is an open Solution
                if (VisualStudioHelper.IsSolutionOpen(_applicationObject) == false)
                {
                    this.ShowErrorMessage(Resources.Error_NoSolution);
                }
                else
                {
                    // Clear event handlers of GeneratorManager
                    GeneratorManager.ClearEventHandlers();

                    // Get the Solution Items
                    List<ProjectItem> solutionItems = 
                        VisualStudioHelper.GetSolutionProjectItems(_applicationObject.Solution);

                    // Get the EDMX Project Items
                    List<ProjectItem> edmxItems = solutionItems
                        .Where(i => i.Name.EndsWith(Resources.EdmxFileExtension))
                        .OrderBy(i => i.Name).ToList();

                    // lstEDMXFiles
                    this.lstEDMXFiles.DataSource = edmxItems;
                    this.lstEDMXFiles.DisplayMember = Resources.ProjectItem_Name;

                    // Get Solution Projects
                    List<Project> solutionProjects = 
                        VisualStudioHelper.GetProjectsFromSolution(_applicationObject.Solution);

                    // lstProjectsDTOs
                    this.lstProjectsDTOs.DataSource = solutionProjects;
                    this.lstProjectsDTOs.DisplayMember = Resources.ProjectItem_Name;

                    // lstProjectsAssemblers
                    this.lstProjectsAssemblers.DataSource = solutionProjects.ToList();
                    this.lstProjectsAssemblers.DisplayMember = Resources.ProjectItem_Name;

                    // cbLogProcess
                    this.cbLogProcess.Checked = LogManager.IsLogActive;

                    // Attach to GeneratorManager events
                    GeneratorManager.OnComplete += new EventHandler<GeneratorOnCompleteEventArgs>(GeneratorManager_OnComplete);
                    GeneratorManager.OnCancel += new EventHandler<GeneratorOnCancelEventArgs>(GeneratorManager_OnCancel);
                    GeneratorManager.OnException += new EventHandler<GeneratorOnExceptionEventArgs>(GeneratorManager_OnException);

                    // Load latest configuration used by the user
                    this.LoadLatestConfiguration();
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorMessage(ex.Message);
            }
        }


        #region UI Events

        /// <summary>
        /// Executed when the window is about to be closed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            VisualStudioHelper.SetStatusBarMessage(Resources.Info_Ready);
        }

        /// <summary>
        /// Executed when the User checks the Custom Header Comment checkbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbCustomHeaderComment_CheckedChanged(object sender, EventArgs e)
        {
            this.txtCustomHeaderComment.Enabled = this.cbCustomHeaderComment.Checked;
        }

        /// <summary>
        /// Executed when the User checks the Generate Assemblers checkbox.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbGenerateAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            this.groupBoxAssemblers.Enabled = this.cbGenerateAssemblers.Checked;
        }

        /// <summary>
        /// Executed when the User checks the Log process checkbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbLogProcess_CheckedChanged(object sender, EventArgs e)
        {
            LogManager.IsLogActive = this.cbLogProcess.Checked;

            if (this.cbLogProcess.Checked)
            {
                MessageBox.Show(string.Format(Resources.Info_LogFile, Resources.LogFilePath),
                    Resources.Info_Caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// Executed when the User checks the Use Default Namespace checkbox of Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbUseDefaultNamespaceAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

                this.txtNamespaceAssemblers.Enabled = false;
                this.txtNamespaceAssemblers.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                this.txtNamespaceAssemblers.Enabled = true;
            }
        }

        /// <summary>
        /// Executed when the User checks the Use Default Namespace checkbox of DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbUseDefaultNamespaceDTOs_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

                this.txtNamespaceDTOs.Enabled = false;
                this.txtNamespaceDTOs.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                this.txtNamespaceDTOs.Enabled = true;
            }
        }

        /// <summary>
        /// Executed when the Used clicks the Close button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Executed when the User clicks the Generate button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnGenerate_Click(object sender, EventArgs e)
        {
            this.Generate();
        }

        /// <summary>
        /// Executed when the User clicks the Help button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_Click(object sender, EventArgs e)
        {
            var helpWin = new HelpWindow();
            helpWin.ShowDialog(this);
        }

        /// <summary>
        /// Executed when the User enters the Help button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_MouseEnter(object sender, EventArgs e)
        {
            this.btnHelp.Image = Resources.img_help_hover;
        }

        /// <summary>
        /// Executed when the User leaves the Help button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_MouseLeave(object sender, EventArgs e)
        {
            this.btnHelp.Image = Resources.img_help;
        }

        /// <summary>
        /// Executed when the User selects a Project from the list of Projects for Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lstProjectsAssemblers_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.lstProjectsAssemblers.SelectedItem != null
                && this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

                this.txtNamespaceAssemblers.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
        }

        /// <summary>
        /// Executed when the User selects a Project from the list of Projects for DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lstProjectsDTOs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.lstProjectsDTOs.SelectedItem != null
                && this.cbUseDefaultNamespaceDTOs.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

                this.txtNamespaceDTOs.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
        }

        /// <summary>
        /// Executed when the User checks one of the Source File Generation Type radio buttons for Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rbSourceFileGenerationTypeAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbOneSourceFileAssemblers.Checked)
            {
                this.txtSourceFileNameAssemblers.Enabled = true;
                this.txtSourceFileNameAssemblers.Text = string.Empty;
            }
            else
            {
                this.txtSourceFileNameAssemblers.Enabled = false;
                this.txtSourceFileNameAssemblers.Text = Resources.Text_DefaultSourceFileName;
            }
        }

        /// <summary>
        /// Executed when the User checks one of the Source File Generation Type radio buttons for DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rbSourceFileGenerationTypeDTOs_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbOneSourceFileDTOs.Checked)
            {
                this.txtSourceFileNameDTOs.Enabled = true;
                this.txtSourceFileNameDTOs.Text = string.Empty;
            }
            else
            {
                this.txtSourceFileNameDTOs.Enabled = false;
                this.txtSourceFileNameDTOs.Text = Resources.Text_DefaultSourceFileName;
            }
        }

        /// <summary>
        /// Executed when the User clicks the Config Export menu button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigExport_Click(object sender, EventArgs e)
        {
            try
            {
                // Validate generation process
                this.ValidateGeneration();

                // Show Save File Dialog
                var dialog = new SaveFileDialog();
                dialog.Filter = Resources.EntitiesToDTOsConfigFileFilter;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Export configuration
                    ConfigurationHelper.Export(this.GetGeneratorManagerParams(), dialog.FileName);

                    // Show OK message
                    VisualStudioHelper.SetStatusBarMessage(Resources.Info_ConfigExportComplete);
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Executed when the User clicks the Config Import menu button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigImport_Click(object sender, EventArgs e)
        {
            try
            {
                // Show Open File Dialog
                var dialog = new OpenFileDialog();
                dialog.Filter = Resources.EntitiesToDTOsConfigFileFilter;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Load the configuration
                    bool showWarnings = true;
                    this.LoadConfiguration(dialog.FileName, showWarnings);

                    // Validate generation process
                    this.ValidateGeneration();

                    // Shoe OK message
                    VisualStudioHelper.SetStatusBarMessage(Resources.Info_ConfigImportComplete);
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        #endregion UI Events

        #region GeneratorManager Events

        /// <summary>
        /// Executed when an Exception is raised by the GeneratorManager.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnException(object sender, GeneratorOnExceptionEventArgs e)
        {
            this.ManageException(e.Exception);
        }

        /// <summary>
        /// Executed when a Cancel event is raised by the GeneratorManager.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnCancel(object sender, GeneratorOnCancelEventArgs e)
        {
            this.Enabled = true;
        }

        /// <summary>
        /// Executed when the GeneratorManager finishes the process.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnComplete(object sender, GeneratorOnCompleteEventArgs e)
        {
            // Close progress window
            this.ProgressWindow.Close();

            // Check Warnings
            if (VisualStudioHelper.ErrorTaskCollectionHasItems())
            {
                // Show Warning message
                MessageBox.Show(Resources.Info_GenerationCompleteWithWarnings, Resources.Info_Caption,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);

                // Show ErrorList pane
                VisualStudioHelper.ShowErrorList();
            }
            else
            {
                // Show OK message
                MessageBox.Show(Resources.Info_GenerationComplete, Resources.Info_Caption, 
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            // Release COM Object (use ReleaseComObject only if it is absolutely required)
            //System.Runtime.InteropServices.Marshal.ReleaseComObject(_applicationObject);

            // Close AddIn
            this.Close();
        }

        #endregion GeneratorManager Events

        #region Methods

        /// <summary>
        /// Gets the Selected Project from the list of Projects
        /// </summary>
        /// <returns></returns>
        private Project GetSelectedProject(ListBox listBox)
        {
            return (listBox.SelectedItem as Project);
        }

        /// <summary>
        /// In case of Exception, this method must be call.
        /// </summary>
        private void ManageException(Exception ex)
        {
            LogManager.LogError(ex);

            if (this.ProgressWindow != null)
            {
                // Close progress window
                this.ProgressWindow.Close();
            }

            this.ShowErrorMessage(string.Format(Resources.Error_ExceptionMessage, ex.Message));

            this.Enabled = true;
        }

        /// <summary>
        /// Shows an error message to the User.
        /// </summary>
        /// <param name="message"></param>
        private void ShowErrorMessage(string message)
        {
            MessageBox.Show(message, Resources.Error_Caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>
        /// Process validations to check if the AddIn is ready to start the generation.
        /// </summary>
        private void ValidateGeneration()
        {
            // General validations
            if(this.lstEDMXFiles.SelectedItem == null)
            {
                throw new InvalidOperationException(Resources.Error_NoEDMXSource);
            }

            #region DTOs validations
            if (this.lstProjectsDTOs.SelectedItem == null)
            {
                throw new InvalidOperationException(Resources.Error_NoTargetProjectDTOs);
            }
            else if (string.IsNullOrWhiteSpace(this.GetSourceFileNamespaceForDTOs()))
            {
                throw new InvalidOperationException(Resources.Error_InvalidNamespaceDTOs);
            }

            // Check the Source File Generation Type for DTOs
            if (this.rbOneSourceFileDTOs.Checked)
            {
                if (string.IsNullOrWhiteSpace(this.txtSourceFileNameDTOs.Text)
                    || this.txtSourceFileNameDTOs.Text.Contains(Resources.Space))
                {
                    throw new InvalidOperationException(Resources.Error_InvalidSourceFileNameDTOs);
                }
            }
            #endregion DTOs validations

            #region Assemblers validations
            if (this.cbGenerateAssemblers.Checked)
            {
                if (this.lstProjectsAssemblers.SelectedItem == null)
                {
                    throw new InvalidOperationException(Resources.Error_NoTargetProjectAssemblers);
                }
                else if (string.IsNullOrWhiteSpace(this.GetSourceFileNamespaceForAssemblers()))
                {
                    throw new InvalidOperationException(Resources.Error_InvalidNamespaceAssemblers);
                }

                // Check the Source File Generation Type for Assemblers
                if (this.rbOneSourceFileAssemblers.Checked)
                {
                    if (string.IsNullOrWhiteSpace(this.txtSourceFileNameAssemblers.Text)
                        || this.txtSourceFileNameAssemblers.Text.Contains(Resources.Space))
                    {
                        throw new InvalidOperationException(Resources.Error_InvalidSourceFileNameAssemblers);
                    }
                }
            }
            #endregion Assemblers validations
        }

        /// <summary>
        /// Gets the Source File Namespace for DTOs.
        /// </summary>
        /// <returns></returns>
        private string GetSourceFileNamespaceForDTOs()
        {
            // Get the target Project for DTOs
            Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

            string sourceNamespace = null;
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                sourceNamespace = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                sourceNamespace = this.txtNamespaceDTOs.Text;
            }

            return sourceNamespace;
        }

        /// <summary>
        /// Gets the Source File Namespace for Assemblers.
        /// </summary>
        /// <returns></returns>
        private string GetSourceFileNamespaceForAssemblers()
        {
            // Get the target Project for Assemblers
            Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

            string sourceNamespace = null;
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                sourceNamespace = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                sourceNamespace = this.txtNamespaceAssemblers.Text;
            }

            return sourceNamespace;
        }

        /// <summary>
        /// Executes the generation process.
        /// </summary>
        private void Generate()
        {
            try
            {
                // Validate generation process
                this.ValidateGeneration();

                // Disable Main Window
                this.Enabled = false;

                // Clear ErrorList pane from ErrorTask produced by EntitiesToDTOs
                VisualStudioHelper.ClearErrorList();

                // Get Generator Manager parameters
                GeneratorManagerParams generatorParams = this.GetGeneratorManagerParams();

                // Show progress window
                this.ProgressWindow = new GenerationProgressWindow(generatorParams.DTOsParams.EDMXProjectItem.Name);
                this.ProgressWindow.Show(this);

                // Save latest configuration
                ConfigurationHelper.Export(generatorParams, ConfigurationHelper.TempFilePath);

                // Start the generation
                GeneratorManager.Generate(generatorParams);
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Gets the parameters for GeneratorManager.
        /// </summary>
        /// <returns></returns>
        private GeneratorManagerParams GetGeneratorManagerParams()
        {
            // Get the EDMX Document as ProjectItem
            var edmxProjectItem = (this.lstEDMXFiles.SelectedItem as ProjectItem);

            // Get Target Project
            Project targetProjectDTOs = this.GetSelectedProject(this.lstProjectsDTOs);
            Project targetProjectAssemblers = this.GetSelectedProject(this.lstProjectsAssemblers);

            // Get Source File Namespace
            string sourceNamespaceDTOs = this.GetSourceFileNamespaceForDTOs();
            string sourceNamespaceAssemblers = this.GetSourceFileNamespaceForAssemblers();

            // Get Source File Name
            string sourceFileNameDTOs = this.txtSourceFileNameDTOs.Text.Trim();
            string sourceFileNameAssemblers = this.txtSourceFileNameAssemblers.Text.Trim();

            // Get the Source File Generation Type for DTOs
            var sourceFileGenerationTypeDTOs = SourceFileGenerationTypeEnum.SourceFilePerClass;
            if (this.rbOneSourceFileDTOs.Checked)
            {
                sourceFileGenerationTypeDTOs = SourceFileGenerationTypeEnum.OneSourceFile;
            }

            // Get the Source File Generation Type for Assemblers
            var sourceFileGenerationTypeAssemblers = SourceFileGenerationTypeEnum.SourceFilePerClass;
            if (this.rbOneSourceFileAssemblers.Checked)
            {
                sourceFileGenerationTypeAssemblers = SourceFileGenerationTypeEnum.OneSourceFile;
            }

            // Get the Association Type
            var associationType = AssociationTypeEnum.KeyProperty;
            if (this.rbAssociationConfigUseClassTypes.Checked)
            {
                associationType = AssociationTypeEnum.ClassType;
            }

            // Source File Header Comment
            string sourceFileHeaderComment = null;
            if (this.cbCustomHeaderComment.Checked)
            {
                sourceFileHeaderComment = this.txtCustomHeaderComment.Text;
            }

            // Set DTOs parameters
            var dtosParams = new GenerateDTOsParams(targetProjectDTOs, edmxProjectItem, sourceFileHeaderComment,
                this.cbUseDefaultNamespaceDTOs.Checked, sourceNamespaceDTOs, this.cbServiceReadyDTOs.Checked, 
                sourceFileGenerationTypeDTOs, sourceFileNameDTOs, associationType, this.cbGenerateDTOConstructors.Checked);
            
            // Set Assemblers parameters
            var assemblersParams = new GenerateAssemblersParams(targetProjectAssemblers, sourceFileHeaderComment,
                this.cbUseDefaultNamespaceAssemblers.Checked, sourceNamespaceAssemblers, sourceFileGenerationTypeAssemblers,
                sourceFileNameAssemblers, this.cbServiceReadyDTOs.Checked, sourceNamespaceDTOs, targetProjectDTOs, 
                edmxProjectItem);

            // Return the result generator parameters
            return new GeneratorManagerParams(dtosParams, assemblersParams, this.cbGenerateAssemblers.Checked);
        }

        /// <summary>
        /// Loads a configuration from the specified file path.
        /// </summary>
        /// <param name="filePath">File path from where to load the configuration.</param>
        /// <param name="showWarnings">Indicates if warnings should be shown.</param>
        /// <returns>True if EDMX Source match, DTOs Target Project match, Assemblers Target Project match. False otherwise.</returns>
        private bool LoadConfiguration(string filePath, bool showWarnings)
        {
            bool edmxSourceFound = false;
            bool dtosProjectFound = false;
            bool assemblersProjectFound = false;
            string warnings = string.Empty;

            // Import configuration
            GeneratorManagerParams config = ConfigurationHelper.Import(filePath);

            // Set EDMX Source
            foreach (ProjectItem projectItem in this.lstEDMXFiles.Items)
            {
                if (projectItem.Name == config.DTOsParams.EDMXName)
                {
                    this.lstEDMXFiles.SelectedItem = projectItem;
                    edmxSourceFound = true;
                    break;
                }
            }

            if (edmxSourceFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_EdmxSourceNotFound, config.DTOsParams.EDMXName);
            }

            // Set Target Project for DTOs
            foreach (Project project in this.lstProjectsDTOs.Items)
            {
                if (project.Name == config.DTOsParams.TargetProjectName)
                {
                    this.lstProjectsDTOs.SelectedItem = project;
                    dtosProjectFound = true;
                    break;
                }
            }

            if (dtosProjectFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_DTOsTargetProjectNotFound, config.DTOsParams.TargetProjectName);
            }

            // Set Target Project for Assemblers
            foreach (Project project in this.lstProjectsAssemblers.Items)
            {
                if (project.Name == config.AssemblersParams.TargetProjectName)
                {
                    this.lstProjectsAssemblers.SelectedItem = project;
                    assemblersProjectFound = true;
                    break;
                }
            }

            if (assemblersProjectFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_AssemblersTargetProjectNotFound, config.AssemblersParams.TargetProjectName);
            }

            // Set Source File namespace for DTOs
            this.cbUseDefaultNamespaceDTOs.Checked = (config.DTOsParams.UseProjectDefaultNamespace && dtosProjectFound);
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                VisualStudioHelper.GetProjectDefaultNamespace(this.GetSelectedProject(this.lstProjectsDTOs));
            }
            else
            {
                this.txtNamespaceDTOs.Text = config.DTOsParams.SourceNamespace;
            }

            // Set Source File namespace for Assemblers
            this.cbUseDefaultNamespaceAssemblers.Checked = (config.AssemblersParams.UseProjectDefaultNamespace && assemblersProjectFound);
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                VisualStudioHelper.GetProjectDefaultNamespace(this.GetSelectedProject(this.lstProjectsAssemblers));
            }
            else
            {
                this.txtNamespaceAssemblers.Text = config.AssemblersParams.SourceNamespace;
            }

            // Set Source File Generation Type
            this.rbSourceFilePerClassDTOs.Checked = true;
            this.rbOneSourceFileDTOs.Checked = (config.DTOsParams.SourceFileGenerationType == SourceFileGenerationTypeEnum.OneSourceFile);
            this.rbSourceFilePerClassAssemblers.Checked = true;
            this.rbOneSourceFileAssemblers.Checked = (config.AssemblersParams.SourceFileGenerationType == SourceFileGenerationTypeEnum.OneSourceFile);

            // Set Source File Name
            this.txtSourceFileNameDTOs.Text = config.DTOsParams.SourceFileName;
            this.txtSourceFileNameAssemblers.Text = config.AssemblersParams.SourceFileName;

            // Set Association Type
            this.rbAssociationConfigUseKeyProperty.Checked = true;
            this.rbAssociationConfigUseClassTypes.Checked = (config.DTOsParams.AssociationType == AssociationTypeEnum.ClassType);

            // Set Source File Header Comment
            this.cbCustomHeaderComment.Checked = (string.IsNullOrWhiteSpace(config.DTOsParams.SourceFileHeaderComment) == false);
            this.txtCustomHeaderComment.Text = config.DTOsParams.SourceFileHeaderComment;

            // Set Service-Ready
            this.cbServiceReadyDTOs.Checked = config.DTOsParams.DTOsServiceReady;

            // Set Generate Assemblers option
            this.cbGenerateAssemblers.Checked = config.GenerateAssemblers;

            if (showWarnings == true)
            {
                // Check Warnings
                if (warnings.Length > 0)
                {
                    // Show warning message
                    MessageBox.Show(string.Format(Resources.Warning_WarningsWhenLoadingConfiguration, warnings),
                        Resources.Warning_Caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            // Return. True if EDMX Source match, DTOs Target Project match, Assemblers Target Project match. False otherwise.
            return (edmxSourceFound && dtosProjectFound && assemblersProjectFound);
        }

        /// <summary>
        /// Loads the latest configuration used by the user.
        /// </summary>
        private void LoadLatestConfiguration()
        {
            try
            {
                // Temp config file exists?
                if (File.Exists(ConfigurationHelper.TempFilePath))
                {
                    // Load latest configuration
                    bool showWarnings = false;
                    bool edmxAndTargetProjectsFound = this.LoadConfiguration(ConfigurationHelper.TempFilePath, showWarnings);

                    if (edmxAndTargetProjectsFound)
                    {
                        // Validate generation process
                        this.ValidateGeneration();

                        // Show OK message
                        VisualStudioHelper.SetStatusBarMessage(Resources.Info_LatestConfigLoaded);
                    }
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        #endregion Methods
    }
}